#include "includes.h"
/*
 * KSP_solver.cpp
 *
 *  Created on: 14/09/2011
 *      Author: rogsoares
 */


// solve system of equations: Ax=y
double KSP_solver(Mat A, Mat pcMatrix, Vec y, Vec x, KSPType ksptype, PCType pctype){
	double startt = MPI_Wtime();
	PetscErrorCode ierr;
	KSP ksp;
	
	ierr = KSPCreate(PETSC_COMM_WORLD,&ksp); CHKERRQ(ierr);

	// Sets the matrix associated with the linear system and a (possibly) different one associated with the preconditioner.
	ierr = KSPSetOperators(ksp,A,pcMatrix,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);

	// KSPFGMRES - Implements the Flexible Generalized Minimal Residual method.
	ierr = KSPSetType(ksp,ksptype);CHKERRQ(ierr);

	// Abstract PETSc object that manages all preconditioners. Returns a pointer to the preconditioner context set with KSPSetPC().
	PC preconditioner;
	ierr = KSPGetPC(ksp,&preconditioner);CHKERRQ(ierr);
	ierr = PCSetType(preconditioner,pctype);CHKERRQ(ierr);

	// Tells the iterative ksp that the initial guess is nonzero; otherwise KSP assumes the initial guess is to be zero (and
	// thus zeros it out before solving). Notes:	If this is not called the X vector is zeroed in the call to KSPSolve().
	
	
	
	//ierr = KSPSetInitialGuessNonzero(ksp,guessNonZero);CHKERRQ(ierr);
	
	ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr);

	// Sets the relative, absolute, divergence, and maximum iteration tolerances used by the default KSP convergence testers.
	ierr = KSPSetTolerances(ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);

	// Sets KSP options from the options database. This routine must be called before KSPSetUp() if the user is to be allowed
	// to set the Krylov type.
	ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr);
	ierr = KSPSolve(ksp,y,x);CHKERRQ(ierr);
	ierr = KSPDestroy(ksp); CHKERRQ(ierr);
	double endt = MPI_Wtime();
	
	//ierr = VecView(x,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr);
	
	return endt-startt;
}
